#ifndef STORAGE_STORAGE_BASE_HPP
#define STORAGE_STORAGE_BASE_HPP

#include "Storage/StorageConfig.hpp"
#include <list>

namespace Storage
{

class StorageFactory;
class StorageCommand;

/// @ingroup Storage
/// @brief It is the base class for all storages.
/// 
/// A storage manages the dedicated storage commands and also knows how to load those case entities.
class STORAGE_API StorageBase
{
	StorageBase& operator=( const StorageBase& );
public:
	/// @brief It initializes the storage.
	/// @param factory the storage factory providing access to other storages this one might depend on.
	explicit StorageBase( StorageFactory& factory);

	/// @brief It deletes the managed commands.
	virtual ~StorageBase();

	/// @brief It gets the storage factory.
	/// @{
	StorageFactory& storageFactory() { return rStorageFactory_; }
	const StorageFactory& storageFactory() const { return rStorageFactory_; }
	/// @}

	/// @brief It appends the specified command to the list of storage commands. 
	/// 
	/// By appending the command, it becomes the owner of that command.
	void pushCommand( StorageCommand* pNewCommand);

	/// @brief It gets the command on the top of the storage command stack or NULL if there is no command on the stack.
	/// @{
	const StorageCommand* topCommand() const;
	StorageCommand* topCommand();
	/// @}

	/// @brief It removes the command from the top of the storage.
	/// @warning The command object is not deleted. The caller should take the ownership of the popped command.
	StorageCommand* popCommand();

	/// @brief It executes the storage commands in the list, then deletes the executed commands.
	virtual void store();


	/// @brief It checks whether there are changes not saved (storage commands that need to be executed).
	virtual bool hasUnsavedChanges() const;

protected:
	StorageFactory& rStorageFactory_;
	typedef std::list< StorageCommand*> StorageCommands;
	StorageCommands commands_;

protected:
	void clearCommands();
};
	
} // namespace Storage

#endif // STORAGE_STORAGE_BASE_HPP
